package cn.echogo.framework.http.imp;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import cn.echogo.framework.http.EGHttpClient;
import cn.echogo.framework.http.EGHttpClientException;
import cn.echogo.framework.http.HttpDataHelper;
import cn.echogo.framework.http.RequestEntity;
import cn.echogo.framework.http.ResponseEntity;
import cn.echogo.framework.http.bak.RequestParams;

public class EGHttpClientImp implements EGHttpClient {

	private static final int DEFAULT_TIMEOUT_CONNECTION = 30 * 1000; // 默认连接超时时间（单位：毫秒）
	private static final int DEFAULT_TIMEOUT_SOCKET = 30 * 1000; // 默认Socket超时时间（单位：毫秒）
	private static final int DEFAULT_BUFFER_SIZE = 8192 * 20;
	private static final String USER_AGENT = "Mozil1a/4.0 (compatible; MS1E 7.0; Windows NT 6.1; WOW64; )";
	private static final String DEFAULT_CHARSET = "UTF-8"; // 默认编码格式
	private static final String CONTENT_TYPE = "application/x-www-form-urlencoded";

	private DefaultHttpClient httpclient = null;

	public EGHttpClientImp() {
		
	}

	@Override
	public ResponseEntity post(String url, RequestParams params) throws EGHttpClientException {
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader("content-type", CONTENT_TYPE);
		httpPost.setEntity(params.getEntity());
		HttpClient httpClient = getHttpClient();
		try {
			HttpResponse httpRsp = httpClient.execute(httpPost);
			if (httpRsp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				throw new EGHttpClientException();
			}
			HttpEntity httpEntity = httpRsp.getEntity();
			ResponseEntity rspEntity = newResponseEntity(httpEntity);
			httpEntity.consumeContent();
			return rspEntity;
		} catch (ClientProtocolException e) {
			throw new EGHttpClientException();
		} catch (IOException e) {
			throw new EGHttpClientException();
		} finally {
			httpPost.abort();
		}
	}

	@Override
	public ResponseEntity get(String url) throws EGHttpClientException {
		HttpGet httpGet = new HttpGet(url);
		HttpClient httpClient = getHttpClient();
		try {
			HttpResponse httpRsp = httpClient.execute(httpGet);
			if (httpRsp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				throw new EGHttpClientException();
			}
			HttpEntity httpEntity = httpRsp.getEntity();
			ResponseEntity rspEntity = newResponseEntity(httpEntity);
			httpEntity.consumeContent();
			return rspEntity;
		} catch (ClientProtocolException e) {
			throw new EGHttpClientException();
		} catch (IOException e) {
			throw new EGHttpClientException();
		} finally {
			httpGet.abort();
		}
	}

	private ResponseEntity newResponseEntity(HttpEntity httpEntity) throws IOException {
		String charset = EntityUtils.getContentCharSet(httpEntity);
		if (charset == null) {
			charset = DEFAULT_CHARSET;
		}
		int length = (int) httpEntity.getContentLength();
		if (length < 0) {
			length = 4096;
		}
		ResponseEntity rspEntity = HttpDataHelper.newJsonResponseEntity(httpEntity.getContent(), charset, length);
		return rspEntity;
	}

	private synchronized DefaultHttpClient getHttpClient() {
		if (httpclient != null) {
			return httpclient;
		}

		int timeoutConnection = DEFAULT_TIMEOUT_CONNECTION;
		int timeoutSocket = DEFAULT_TIMEOUT_SOCKET;
		int bufferSize = DEFAULT_BUFFER_SIZE;

		HttpParams httpParameters = new BasicHttpParams();

		ConnManagerParams.setMaxTotalConnections(httpParameters, 10);
		ConnManagerParams.setMaxConnectionsPerRoute(httpParameters, new ConnPerRouteBean(8));

		HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
		HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
		HttpConnectionParams.setSocketBufferSize(httpParameters, bufferSize);

		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
		ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(httpParameters, schemeRegistry); // 线程安全

		HttpClientParams.setRedirecting(httpParameters, true);
		HttpClientParams.setCookiePolicy(httpParameters, CookiePolicy.BROWSER_COMPATIBILITY);
		HttpProtocolParams.setUserAgent(httpParameters, USER_AGENT);

		httpclient = new DefaultHttpClient(mgr, httpParameters);

		// 自动重连策略
		httpclient.setHttpRequestRetryHandler(new EGHttpRequestRetryHandler());

		return httpclient;
	}

}
